/*******************************************************************************
 *
 *      Filename: Matrix3x3.h
 *   Description: 
 *        Author: [kb]ypp
 *    Created at: October 24, 2005
 * Last modified: 
 *
 ******************************************************************************/

#ifndef MATRIX3X3_H
#define MATRIX3X3_H

class vec3;

//! @brief Class to represent 3x3 matrix
//!
//! Matrix represented as:
//!
//!     ( m11 m12 m13 )
//! M = ( m21 m22 m23 )
//!     ( m31 m32 m33 )
//!
//! or (in OpenGL-like column-major order)
//!
//!     ( m[0] m[3] m[6] )
//! M = ( m[1] m[4] m[7] )
//!     ( m[2] m[5] m[8] )
//!
//! All matrix elements are float`s.
class mat3 {
public:
	union {
		struct {
			float m11, m21, m31, m12, m22, m32, m13, m23, m33;
		};
		float m[ 9 ];
	};
	
	//! @brief Default constructor
	mat3();
	//! @brief Copy-constructor
	mat3( const mat3 &mat );
	//! @brief Constructor to initialize the matrix with given values
	mat3( float a11, float a12, float a13,
		  float a21, float a22, float a23,
		  float a31, float a32, float a33 );
	
	//! @brief Assignment operator
	const mat3& operator=( const mat3& rv );
	//! @brief Multiply 3x3 matrix A by 3x3 matrix B
	friend const mat3 operator*( const mat3 &a, const mat3 &b );
	//! @brief Multiply 3x3 matrix by 3D vector v
	friend const vec3 operator*( const mat3 &mat, const vec3 &v );
	
	//! @brief Equality (with tolerance) check
	friend bool operator==( const mat3 &lv, const mat3 &rv );
	//! @brief Non-equality (with tolerance) check
	friend bool operator!=( const mat3 &lv, const mat3 &rv );
	
	//! @brief Set a matrix to the identity
	void loadIdentity();
	//! @brief Calculate the determinant of a 3x3 matrix
	friend float det( const mat3 &mat );
	//! @brief Calculate the transpose matrix
	friend const mat3 transpose( const mat3 &mat );
	//! @brief Calculate the inverse of a 3x3 matrix
	friend const mat3 inv( const mat3 &mat );
	
	//! @brief Get the matrix to perform rotation about the x-axis
	static const mat3 rotateX( float theta );
	//! @brief Get the matrix to perform rotation about the y-axis
	static const mat3 rotateY( float theta );
	//! @brief Get the matrix to perform rotation about the z-axis
	static const mat3 rotateZ( float theta );
	//! @brief Get the matrix to perform rotation about an arbitrary axis
	static const mat3 rotateAxis( const vec3 &axis, float theta );
};

#endif // MATRIX3X3_H
